#ifndef _OSC_AES_H_
#define _OSC_AES_H_

#include <stdio.h>
#include <string.h>
#include <pthread.h>
#include <time.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdarg.h>
#include <netdb.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <fcntl.h>

#define AES_ENCRYPT 1
#define AES_DECRYPT 0

#define XOR_KEY_COUNT 8

#define BK_AES_IV_LEN (16)
#define BK_AES_KEY_LEN (32)

#define POW_LEN (256)
#define LOG_LEN (256)

/**
 * \brief          AES context structure
 */
typedef struct
{
    int nr;                /*!<  number of rounds  */
    unsigned long *rk;     /*!<  AES round keys    */
    unsigned long buf[68]; /*!<  unaligned data    */
} StOscAesContext;

#ifdef __cplusplus
extern "C"
{
#endif

/**
 * \brief          AES key schedule (encryption)
 *
 * \param ctx      AES context to be initialized
 * \param key      encryption key
 * \param keysize  must be 128, 192 or 256
 */
void OscAes_SetKey_Enc(StOscAesContext *ctx, unsigned char *key, int keysize);

/**
 * \brief          AES key schedule (decryption)
 *
 * \param ctx      AES context to be initialized
 * \param key      decryption key
 * \param keysize  must be 128, 192 or 256
 */
void OscAes_SetKey_Dec(StOscAesContext *ctx, unsigned char *key, int keysize);

/**
 * \brief          AES-ECB block encryption/decryption
 *
 * \param ctx      AES context
 * \param mode     AES_ENCRYPT or AES_DECRYPT
 * \param input    16-byte input block
 * \param output   16-byte output block
 */
void OscAes_Crypt_Ecb(StOscAesContext *ctx,int mode,unsigned char input[16], unsigned char output[16]);

/**
 * \brief          AES-CBC buffer encryption/decryption
 *
 * \param ctx      AES context
 * \param mode     AES_ENCRYPT or AES_DECRYPT
 * \param length   length of the input data
 * \param iv       initialization vector (updated after use)
 * \param input    buffer holding the input data
 * \param output   buffer holding the output data
 */
void OscAes_Crypt_Cbc(StOscAesContext *ctx, int mode, int length, unsigned char iv[16],
                      unsigned char *input, unsigned char *output, int *output_len);

/**
 * \brief          AES-CFB128 buffer encryption/decryption
 *
 * \param ctx      AES context
 * \param mode     AES_ENCRYPT or AES_DECRYPT
 * \param length   length of the input data
 * \param iv_off   offset in IV (updated after use)
 * \param iv       initialization vector (updated after use)
 * \param input    buffer holding the input data
 * \param output   buffer holding the output data
 */
void OscAes_Crypt_Cfb128(StOscAesContext *ctx, int mode, int length, int *iv_off, unsigned char iv[16],
                         unsigned char *input, unsigned char *output);

int OscAes_128Enc(char *aes_iv, char *aes_key, char *source, int source_len, char *dec, int *dec_len);
int OscAes_128Dec(char *aes_iv, char *aes_key, char *source, int source_len, char *dec, int *dec_len);

char *OscAes_128AndBase64_Encode(char *rxdata);
char *OscAes_128AndBase64_Decode(char *rxdata);

#ifdef __cplusplus
}
#endif

#endif
